`timescale 1ns/100ps
`default_nettype none

/* NOTE:
* - 将图像数据写入SDRAM
*/

//`define ENABLE_HUB_PORT_OFFSET

module pixel_save_sdram_top (
    // system signal
    input  wire         I_sclk,  // 125M
    input  wire         I_sdram_clk, // 150M
    input  wire         I_rst_n,
    //config
    input  wire         I_cfg_light_adj_en,  // 全局亮度调整
    input  wire         I_cfg_temp_adj_en,   // 全局色温调整
    input  wire         I_cfg_color_adj_en,  // 全局色度调整
    input  wire         I_cfg_pixel_adj_en,  // 逐点色度调整
    input  wire         I_cfg_gap_adj_en,    // 缝隙调整
    input  wire [15:0]  I_cfg_temp_coe_r,    // 色温调整系数
    input  wire [15:0]  I_cfg_temp_coe_g,    // 色温调整系数
    input  wire [15:0]  I_cfg_temp_coe_b,    // 色温调整系数
    input  wire [15:0]  I_cfg_light_coe,     // 整体亮度系数
    input  wire [15:0]  I_cfg_color_coe_r0,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_g0,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_b0,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_r1,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_g1,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_b1,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_r2,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_g2,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_b2,  // 全局色度调整系数
    input  wire         I_cfg_contrast_en,   // 对比度使能
    input  wire [7:0]   I_cfg_contrast_coe,  // 对比度系数
    
    input  wire         I_cfg_pixel_adj_mode,     
    input  wire [1:0]   I_cfg_scan_mode,
    input  wire [1:0]   I_cfg_box_dir,       // 箱体方向
    input  wire [1:0]   I_cfg_col_loop,      // 列模式读取循环次数(数据组数/8,向上取整)
    input  wire [7:0]   I_cfg_col_step,      // 列模式每次读地址间隔
    input  wire [7:0]   I_cfg_port_height,
    input  wire [3:0]   I_cfg_block_max,
    // config
    input  wire [10:0]  I_cfg_scan_length, // 一扫的像素数量（包含虚点）
    input  wire [5:0]   I_cfg_port_max,
    input  wire [5:0]   I_cfg_scan_max,
    input  wire [3:0]   I_cfg_sector_count,
    input  wire [10:0]  I_cfg_sector_width,
    input  wire [10:0]  I_cfg_sector_height,
    input  wire [10:0]  I_cfg_win_col_num,   // 带载列数（宽度）
    input  wire [10:0]  I_cfg_win_row_num,   // 带载行数（高度）
    
    // gamma
    output wire         O_gamma_start,
    output wire [7:0]   O_gamma_data,
    input  wire [15:0]  I_gamma_result,
    // gap info
    output wire         O_gap_coe_req,
    output wire [9:0]   O_gap_coe_row,
    input  wire         I_gap_coe_busy,
    output wire         O_gap_coe_ack,
    input  wire [15:0]  I_gap_coe_val,
    // input frame
    input  wire         I_frame_start,
    input  wire [1:0]   I_frame_id,  // 用于选定第二次SDRAM SDRAM存储区
    input  wire         frame_req,
    input  wire [1:0]   frist_frame,//第一次SDRAM的切换
  
    //sdram mux  one read
    output wire         O_read_sdram_req,
    input  wire         I_read_sdram_ack,
    input  wire         I_read_sdram_irq,
    output wire         O_read_sdram_cs_n,
    output wire         O_read_sdram_ras_n,
    output wire         O_read_sdram_cas_n,
    output wire         O_read_sdram_we_n,
    output wire [1:0]   O_read_sdram_ba,
    output wire [10:0]  O_read_sdram_addr,
    output wire [31:0]  O_read_sdram_dq_out,
    input  wire [31:0]  I_read_sdram_dq_in,
    output wire         O_read_sdram_dq_oe,
    output wire [3:0]   O_read_sdram_dqm,
    
    // sdram mux two write
    output wire         O_write_sdram_req,
    input  wire         I_write_sdram_ack,
    input  wire         I_write_sdram_irq,
    output wire         O_write_sdram_cs_n,
    output wire         O_write_sdram_ras_n,
    output wire         O_write_sdram_cas_n,
    output wire         O_write_sdram_we_n,
    output wire [1:0]   O_write_sdram_ba,
    output wire [10:0]  O_write_sdram_addr,
    output wire [31:0]  O_write_sdram_dq_out,
    input  wire [31:0]  I_write_sdram_dq_in,
    output wire         O_write_sdram_dq_oe,
    output wire [3:0]   O_write_sdram_dqm
);
//------------------------Parameter----------------------

//------------------------Local signal-------------------
wire        req_sr;
// pixel_crop
wire        line_start;
wire        line_end;
wire [9:0]  line_num;
wire        pixel_valid;
wire [9:0]  pixel_col;
wire [23:0] pixel_gray;

wire        line_start_2;
wire        line_end_2;
wire [9:0]  line_num_2;
wire        pixel_valid_2;
wire [9:0]  pixel_col_2;
wire [23:0] pixel_gray_2;

// line output
wire        row_start;
wire [9:0]  row_num;
wire        row_ready;
wire        row_ack;
wire        pixel_req;
wire [7:0]  pixel_data;

// pixel_writer_top
wire        write_start;
wire        write_busy;
wire [20:0] write_addr;
wire [5:0]  write_len;
wire [7:0]  write_data;

//line_row_buf
wire    line_start_buf;
wire    line_end_buf  ;
wire        ram_wclk;
wire        ram_wren;
wire [9:0]  ram_addr;
wire [23:0] ram_data;

//to save_ctrl
wire        row_start_ctrl  ;
wire        row_ready_ctrl  ;
wire        row_ack_ctrl    ;
wire        pixel_req_ctrl ;
wire [7:0]  pixel_data_ctrl;

//pixel_gray_reader
wire         read_req;
wire         read_busy;
wire         frame_enable;
wire         read_req_sr;
wire         coe_load_req;
wire         coe_load_busy;
wire         intial_valu;
wire         coe_read_sr;
wire         pre_read    ;
wire         pre_read_r  ;
//coe
wire         pixel_coe_ack;
wire [15:0]  pixel_coe_r;
wire [15:0]  pixel_coe_g;
wire [15:0]  pixel_coe_b;

wire            sdram_req           ;
wire    [20:0]  sdram_addr          ;
wire    [9:0]   sdram_len           ;
wire    [2:0]   sdram_req_cnt       ;
wire    [20:0]  sdram_add           ;
wire    [20:0]  sdram_col_add       ;
wire    [20:0]  sdram_add1          ;
wire    [1:0]   sdram_mode          ;
wire            sdram_busy          ;
wire            sdram_coe_busy      ;

wire            gap_coe_req        ;
wire    [9:0]   gap_coe_addr_row   ;
wire    [9:0]   gap_coe_addr_col   ;
wire    [9:0]   gap_coe_len        ;
wire    [2:0]   gap_coe_req_cnt    ;
wire    [9:0]   gap_coe_add        ;
wire            gap_coe_dir        ;
wire            gap_coe_busy       ;

wire            sdram_data_sel      ;
wire            port_scan_start     ;
wire            rdata_sel           ;
wire    [5:0]   save_port_id        ;
wire    [5:0]   save_scan_id        ;
wire            save_busy           ;

wire            coe_ram_clk         ;
wire            coe_ram_wren_r      ;
wire            coe_ram_wren_g      ;
wire            coe_ram_wren_b      ;
wire    [31:0]  coe_ram_data        ;
wire    [7:0]   coe_ram_addr        ;

wire            sdram_dir           ;
wire            sdram_coe_buay      ;


pixel_read_ctrl  pixel_read_ctrl(
    .I_sclk             (I_sclk             ),
    .I_rst_n            (I_rst_n            ),
      
    .I_frame_start      (I_frame_start      ),   

    .I_line_max_pixel   (I_cfg_scan_length  ),//一扫的像素---4的倍数。 从1 开始计数
    .I_cfg_port_max     (I_cfg_port_max     ),//最大port_id 从0计数
    .I_cfg_scan_max     (I_cfg_scan_max     ),//最大scan_id 从0 计数
    .I_cfg_box_dir      (I_cfg_box_dir      ),//箱体方向
    .I_cfg_sector_count (I_cfg_sector_count ),//多开数量
    .I_cfg_sector_width (I_cfg_sector_width ),//分区宽度
    .I_cfg_sector_height(I_cfg_sector_height),//区域的高度
    .I_cfg_port_height  (I_cfg_port_height  ),//port的高度
    .I_cfg_block_max    (I_cfg_block_max    ),//列模式下多开的数量
    .I_cfg_pixel_adj_en (I_cfg_pixel_adj_en ),// 逐点调整
    .I_cfg_pixel_adj_mode(I_cfg_pixel_adj_mode),//亮度或色度调整
    .I_cfg_gap_adj_en   (I_cfg_gap_adj_en   ),// 缝隙调整
    .I_cfg_win_col_num  (I_cfg_win_col_num  ),// 带载列数（宽度）
    .I_cfg_win_row_num  (I_cfg_win_row_num  ),// 带载行数（高度）

    .I_frame_req        (frame_req          ),
    .I_frist_frame      (frist_frame        ),//第一次SDRAM的切换
    //sdram 操作
    .O_sdram_req        (sdram_req          ),
    .O_cfg_sdram_addr   (sdram_addr         ),// 
    .O_cfg_sdram_len    (sdram_len          ),//现在必需是4的倍数
    .O_cfg_sdram_req_cnt(sdram_req_cnt      ),//读几行 从0开始计数 相当有几折
    .O_cfg_sdram_add    (sdram_add          ),//每行之间的地址差
    .O_cfg_sdram_col_add(sdram_col_add      ),
    .O_cfg_sdram_add1   (sdram_add1         ),//色度校正中每个分量的地址差
    .O_cfg_sdram_mode   (sdram_mode         ),// 0:像素 1：亮度校正 2：色度校正 
    .O_cfg_sdram_dir    (sdram_dir      ),// 0：按行读  1：按列读
    .I_sdram_busy       (sdram_busy         ),//sdram读模块忙
    .O_cfg_sdram_data_sel(sdram_data_sel    ),//读回的数据缓存到那个buf
    
    //
    .O_gap_coe_req      ( O_gap_coe_req       ),//计算拼缝数据
    .O_gap_coe_addr_row ( O_gap_coe_row       ), //gap_coe_addr_row  ),// 
    .O_gap_coe_addr_col ( gap_coe_addr_col  ),// 
    .O_gap_coe_len      ( gap_coe_len       ),//现在必需是4的倍数
    .O_gap_coe_req_cnt  ( gap_coe_req_cnt   ),//读几行 从0开始计数 相当有几折
    .O_gap_coe_add      ( gap_coe_add       ),//每行之间的地址差
    .O_gap_coe_dir      ( gap_coe_dir       ),
    .I_gap_coe_busy     ( I_gap_coe_busy      ),//计算拼缝忙
    
    //像素处理
    // .I_frame_buf_sel    (                   ),//帧切换
    .O_save_req         (  port_scan_start  ),//保存行读求
    .O_save_req_data_sel(  rdata_sel        ),//那个缓存buf
    .O_save_port_id     (  save_port_id     ),
    .O_save_scan_id     (  save_scan_id    ),
    .I_save_busy        (  save_busy       )
    
);



//------------------------Instantiation------------------
// coe_reader
coe_reader coe_rd (/*{{{*/
    .I_sclk             (I_sclk             ),
    .I_sdram_clk        (I_sdram_clk        ),
    .I_rst_n            (I_rst_n            ),
    
    .I_coe_ram_clk      (coe_ram_clk        ),
    .I_coe_ram_wren_r   (coe_ram_wren_r     ),
    .I_coe_ram_wren_g   (coe_ram_wren_g     ),
    .I_coe_ram_wren_b   (coe_ram_wren_b     ),
    .I_coe_ram_data     (coe_ram_data       ),
    .I_coe_ram_addr     (coe_ram_addr       ),
    
    .I_cfg_coe_mode     (I_cfg_pixel_adj_mode ),
    .I_cfg_scan_length  (I_cfg_scan_length    ), //  一行的像素 1 计数
    .I_cfg_box_dir      (I_cfg_box_dir        ),
    
    .I_coe_load_req     (port_scan_start       ),
    .I_coe_ack          (pixel_coe_ack      ),
    .O_coe_r            (pixel_coe_r ),
    .O_coe_g            (pixel_coe_g ),
    .O_coe_b            (pixel_coe_b )
);/*}}}*/
// 第一次读SDRAM
//pixel_gray_reader
pixel_gray_reader pixel_gray_reader(/*{{{*/
    .I_sclk             (I_sclk             ),          //
    .I_sdram_clk        (I_sdram_clk        ),          //
    .I_rst_n            (I_rst_n            ),
    
    //coe
    .O_coe_ram_clk      (coe_ram_clk        ),
    .O_coe_ram_wren_r   (coe_ram_wren_r     ),
    .O_coe_ram_wren_g   (coe_ram_wren_g     ),
    .O_coe_ram_wren_b   (coe_ram_wren_b     ),
    .O_coe_ram_data     (coe_ram_data       ),
    .O_coe_ram_addr     (coe_ram_addr       ),
    
     // line_row_buf     
    .O_ram_wclk         (ram_wclk           ),
    .O_ram_wren         (ram_wren           ),
    .O_ram_addr         (ram_addr           ),
    .O_ram_data         (ram_data           ),              
    
    .I_sdram_req        (sdram_req          ),
    .I_cfg_sdram_addr   (sdram_addr         ),
    .I_cfg_sdram_len    (sdram_len          ),
    .I_cfg_sdram_req_cnt(sdram_req_cnt      ),
    .I_cfg_sdram_add    (sdram_add      ),
    .I_cfg_sdram_col_add(sdram_col_add      ),
    .I_cfg_sdram_add1   (sdram_add1         ),
    .I_cfg_sdram_mode   (sdram_mode         ),
    .I_cfg_sdram_dir    (sdram_dir          ),
    .O_sdram_busy       (sdram_busy         ),
    .O_sdram_coe_busy   (sdram_coe_busy     ),
    
    //SDRAM 接口               
    .O_mux_req          (O_read_sdram_req   ),
    .I_mux_ack          (I_read_sdram_ack   ),
    .I_mux_irq          (I_read_sdram_irq   ), // 中断
    .O_mux_cs_n         (O_read_sdram_cs_n  ),
    .O_mux_ras_n        (O_read_sdram_ras_n ),
    .O_mux_cas_n        (O_read_sdram_cas_n ),
    .O_mux_we_n         (O_read_sdram_we_n  ),
    .O_mux_ba           (O_read_sdram_ba    ),
    .O_mux_addr         (O_read_sdram_addr  ),
    .O_mux_dq_out       (O_read_sdram_dq_out),
    .I_mux_dq_in        (I_read_sdram_dq_in ),
    .O_mux_dq_oe        (O_read_sdram_dq_oe ),
    .O_mux_dqm          (O_read_sdram_dqm   )
);/**}}}*/

//第一次从SDRAM 读出一行的数据存进buf 里面
line_row_buf line_row_buf(/*{{{*/
    .I_sclk(I_sclk),  // 12 
    .I_rst_n(I_rst_n),
     
    .I_pixel_valid  (ram_wren),
    .I_pixel_col    (ram_addr), 
    .I_pixel_buf_wsel(sdram_data_sel),
    .I_pixel_gray   (ram_data),
    .I_pixel_clk    (ram_wclk),

     // save_ctrl
    .I_pixel_start  ( port_scan_start   ),
    .I_pixel_buf_rsel(rdata_sel     ),
    .I_pixel_req    (pixel_req_ctrl ),  //读buf请求
    .O_pixel_data   (pixel_data_ctrl)    //buf数据
);
/*}}}*/

// pixel_save_ctrl
//读出写一行buf 的数据的控制信号，以及开始存第二次sdram的控制
pixel_save_ctrl_3sdram  pixel_save_ctrl_3sdram(
    .I_sclk             (I_sclk             ),
    .I_rst_n            (I_rst_n            ),
                        
    .I_frame_start      (port_scan_start    ),    
    .I_save_port_id     (save_port_id       ),
    .I_save_scan_id     (save_scan_id       ),    
    
    .frame_buf_sel      (I_frame_id         ), //帧切换
    
    .I_cfg_scan_mode    (I_cfg_scan_mode    ),                
    .I_cfg_pixel_adj_en (I_cfg_pixel_adj_en  ),
    .I_cfg_gap_adj_en   (I_cfg_gap_adj_en    ),
    .I_cfg_scan_length  (I_cfg_scan_length   ), //  一行的像素 1 计数
    .I_cfg_scan_max     (I_cfg_scan_max      ),//0计数
    .I_cfg_port_max     (I_cfg_port_max      ),//0计数   

    
    .I_coe_load_busy    (sdram_coe_busy       ),   
    
    .I_gap_coe_busy     (I_gap_coe_busy      ),
    
    //line_row_buf                                    

    .O_pixel_req        (pixel_req_ctrl      ), 
    .I_pixel_data       (pixel_data_ctrl     ), 
    
    .O_write_start      (write_start         ), 
    .I_write_busy       (write_busy          ), 
    .O_write_addr       (write_addr          ), 
    .O_write_len        (write_len           ), 
    .O_write_data       (write_data          ),

    .O_save_busy        (save_busy           )
);


// pixel_writer_top
pixel_writer_top writer (/*{{{*/
    .I_sclk             ( I_sclk ),
    .I_sdram_clk        ( I_sdram_clk ),
    .I_rst_n            ( I_rst_n ),
    .I_cfg_scan_mode    ( I_cfg_scan_mode ),
    .I_cfg_box_dir      ( /*I_cfg_box_dir*/0 ),
    .I_cfg_col_loop     ( I_cfg_col_loop ),
    .I_cfg_light_adj_en ( I_cfg_light_adj_en ),
    .I_cfg_temp_adj_en  ( I_cfg_temp_adj_en ),
    .I_cfg_color_adj_en ( I_cfg_color_adj_en ),
    .I_cfg_pixel_adj_en ( I_cfg_pixel_adj_en ),
    .I_cfg_gap_adj_en   ( I_cfg_gap_adj_en ),
    .I_cfg_temp_coe_r   ( I_cfg_temp_coe_r ),
    .I_cfg_temp_coe_g   ( I_cfg_temp_coe_g ),
    .I_cfg_temp_coe_b   ( I_cfg_temp_coe_b ),
    .I_cfg_light_coe    ( I_cfg_light_coe ),
    .I_cfg_color_coe_r0 ( I_cfg_color_coe_r0 ),
    .I_cfg_color_coe_g0 ( I_cfg_color_coe_g0 ),
    .I_cfg_color_coe_b0 ( I_cfg_color_coe_b0 ),
    .I_cfg_color_coe_r1 ( I_cfg_color_coe_r1 ),
    .I_cfg_color_coe_g1 ( I_cfg_color_coe_g1 ),
    .I_cfg_color_coe_b1 ( I_cfg_color_coe_b1 ),
    .I_cfg_color_coe_r2 ( I_cfg_color_coe_r2 ),
    .I_cfg_color_coe_g2 ( I_cfg_color_coe_g2 ),
    .I_cfg_color_coe_b2 ( I_cfg_color_coe_b2 ),
    .I_cfg_contrast_en  ( I_cfg_contrast_en ),
    .I_cfg_contrast_coe ( I_cfg_contrast_coe ),
    .O_pixel_coe_ack    ( pixel_coe_ack ),
    .I_pixel_coe_r      ( pixel_coe_r ),
    .I_pixel_coe_g      ( pixel_coe_g ),
    .I_pixel_coe_b      ( pixel_coe_b ),
    .O_gamma_start      ( O_gamma_start ),
    .O_gamma_data       ( O_gamma_data ),
    .I_gamma_result     ( I_gamma_result ),
    .O_gap_coe_ack      ( O_gap_coe_ack ),
    .I_gap_coe_val      ( I_gap_coe_val ),
    
    .I_write_start      ( write_start ),
    .O_write_busy       ( write_busy ),
    .I_write_addr       ( write_addr ),
    .I_write_len        ( write_len  ),
    .I_write_data       ( write_data ),
    
    .O_mux_req          ( O_write_sdram_req    ),
    .I_mux_ack          ( I_write_sdram_ack    ),
    .I_mux_irq          ( I_write_sdram_irq    ),
    .O_mux_cs_n         ( O_write_sdram_cs_n   ),
    .O_mux_ras_n        ( O_write_sdram_ras_n  ),
    .O_mux_cas_n        ( O_write_sdram_cas_n  ),
    .O_mux_we_n         ( O_write_sdram_we_n   ),
    .O_mux_ba           ( O_write_sdram_ba     ),
    .O_mux_addr         ( O_write_sdram_addr   ),
    .O_mux_dq_out       ( O_write_sdram_dq_out ),
    .I_mux_dq_in        ( I_write_sdram_dq_in  ),
    .O_mux_dq_oe        ( O_write_sdram_dq_oe  ),
    .O_mux_dqm          ( O_write_sdram_dqm    )
);/*}}}*/


endmodule

`default_nettype wire

// vim:set ts=4 sw=4 et fenc=utf-8 fdm=marker:
